#include <iostream>
#include <memory>

// Step 1: 抽象产品类：按钮
class Button {
public:
    virtual ~Button() = default;
    virtual void render() const = 0;
};

// Step 2: 抽象产品类：文本框
class TextField {
public:
    virtual ~TextField() = default;
    virtual void render() const = 0;
};

// Step 3: 具体产品类：Windows风格的按钮
class WindowsButton : public Button {
public:
    void render() const override {
        std::cout << "Rendering a button in Windows style.\n";
    }
};

// Step 4: 具体产品类：Windows风格的文本框
class WindowsTextField : public TextField {
public:
    void render() const override {
        std::cout << "Rendering a text field in Windows style.\n";
    }
};

// Step 5: 具体产品类：Mac风格的按钮
class MacButton : public Button {
public:
    void render() const override {
        std::cout << "Rendering a button in Mac style.\n";
    }
};

// Step 6: 具体产品类：Mac风格的文本框
class MacTextField : public TextField {
public:
    void render() const override {
        std::cout << "Rendering a text field in Mac style.\n";
    }
};

// Step 7: 抽象工厂接口
class GUIFactory {
public:
    virtual ~GUIFactory() = default;
    virtual std::unique_ptr<Button> createButton() const = 0;
    virtual std::unique_ptr<TextField> createTextField() const = 0;
};

// Step 8: 具体工厂类：Windows工厂
class WindowsFactory : public GUIFactory {
public:
    std::unique_ptr<Button> createButton() const override {
        return std::make_unique<WindowsButton>();
    }
    
    std::unique_ptr<TextField> createTextField() const override {
        return std::make_unique<WindowsTextField>();
    }
};

// Step 9: 具体工厂类：Mac工厂
class MacFactory : public GUIFactory {
public:
    std::unique_ptr<Button> createButton() const override {
        return std::make_unique<MacButton>();
    }

    std::unique_ptr<TextField> createTextField() const override {
        return std::make_unique<MacTextField>();
    }
};

// Step 10: 客户端代码
void renderUI(const GUIFactory& factory) {
    auto button = factory.createButton();
    auto textField = factory.createTextField();
    button->render();
    textField->render();
}

int main() {
    std::cout << "Rendering Windows UI:\n";
    WindowsFactory windowsFactory;
    renderUI(windowsFactory);

    std::cout << "\nRendering Mac UI:\n";
    MacFactory macFactory;
    renderUI(macFactory);

    return 0;
}